export function ichart(dom,initopts={}){
	let app = new PIXI.Application({
		backgroundAlpha:0,
		antialias: true//平滑曲线
	});
	let pnode=document.createElement('div');
	app.renderer.type = PIXI.RENDERER_TYPE.WEBGL;//设置渲染器类型为WebGL
	pnode.innerHTML=`
		<div class="ichart-left" unit=""></div>
		<div class="ichart-right">
			<div class="ichart-right-top">
				<div class="ichart-right-top-point">
					<div class="ichart-right-tip">
						<div class="ichart-right-tip-title">15200</div>
						<div class="ichart-right-tip-content">
							<!--<div class="ichart-right-tip-line">
								<span class="ichart-right-tip-color"></span>
								name：value
							</div>-->
						</div>
					</div>
				</div>
			</div>
			<div class="ichart-right-bottom"  unit=""></div>
		</div>
	`;
	pnode.className='ichart';
	app.view.className="ichart-canvas";
	const leftnode=pnode.querySelector('.ichart-left');
	//const rightnode=pnode.querySelector('.ichart-right');
	const topnode=pnode.querySelector('.ichart-right-top');
	const bottomnode=pnode.querySelector('.ichart-right-bottom');
	const pointnode=pnode.querySelector('.ichart-right-top-point');
	const tipnode=pnode.querySelector('.ichart-right-tip');
	const tipTitlenode=pnode.querySelector('.ichart-right-tip-title');
	const tipContentnode=pnode.querySelector('.ichart-right-tip-content');
	topnode.appendChild(app.view);
	dom.appendChild(pnode);
	
	const lineColor=[
		"#0068b2","#ED943E","#17CD84","#29B7D3",
		"#E95338","#7151b5","#51C278","#D43D78",
		"#74981B","#3D4C88","#864C5F","#4066A2",
		"#2A8A3C","#2E3AC8"
	];
	
	let len;//数据总长度
	let start=0;//开始位置
	let end;//结束位置
	let customYMinMax;//是否自定义Y轴最大最小值 
	
	let dataMin,dataMax,width,height;
	let cacheData={//数据缓存
		x:[],y:[],canvasX:[],canvasY:[],currentY:[],currentX:[],lineStyle:[],
		opts:{
			left:60,top:20,right:20,bottom:30,showTip:false,
			width:initopts.width || dom.offsetWidth,
			height:initopts.height || dom.offsetHeight
		}
	}
	
	let iswheel;//是否已经触发滚轮事件
	let ismouseMove;//是否已经触发手动事件
	let ismouseDown;//鼠标是否已经按钮
	let oldpos,oldstart,oldend;//位置缓存
	
	//鼠标滚动响应
	function wheel(ev){
		if(iswheel)return;
		iswheel=true;
		setTimeout(()=>iswheel=false,50);
		ismouseDown=false;
		let c=end-start;
		//放大时位置差小于20或缩小时开始结束位置同时超除范围，禁止缩放
		if((c<20 && ev.deltaY<0) || (ev.deltaY>0 && start<=0 && end>=len)){
			return;
		}
		let stepNum=parseInt(c*step);//计算需要增减的总点数
		let startNum=parseInt(ev.offsetX/width*stepNum);//开始位置需要增减的点数，为了以鼠标所在位置为中心进行缩放
		let endNum=stepNum-startNum;//结束位置需要增减的点数，为了以鼠标所在位置为中心进行缩放
		if(ev.deltaY<0){
			//放大
			start+=startNum;
			end-=endNum;
		}else{
			//缩小
			start-=startNum;
			end+=endNum;
		}
		if(start<0)start=0;
		if(end>=len)end=len;
		console.time();
		cacheData.y.forEach((v,k)=>draw(k));
		console.timeEnd();
	}
	//鼠标按下响应
	function mousedown(ev){
		ismouseDown=true;
		oldpos=ev.offsetX;
		oldstart=start;
		oldend=end;
		pointnode.style.display='none';
	}
	//鼠标拖动响应
	function mousemove(ev){
		if(ismouseDown){
			if(ismouseMove)return;
			ismouseMove=true;
			setTimeout(()=>ismouseMove=false,20);
			let c=oldpos-ev.offsetX;//大于0往右移，小于0左移
			let movex=parseInt(c/width*(end-start));//将鼠标移动距离转换为图形滚动点数
			if((c<0 && start<=0) || (c>0 && end>=len))return;//拖动最左或最右时禁止拖动
			//console.log({c,start,end,len});
			start=oldstart+movex;//重新设置图形开始位置
			end=oldend+movex;//重新设置图形结束位置
			if(start<0)start=0;
			if(end>len)end=len;
			cacheData.y.forEach((v,k)=>draw(k));			
		}else{			
			let index=parseInt(ev.offsetX/width*cacheData.currentY[0].length);
			canvasMove(index);			
		}
	}
	//鼠标离开或松开响应
	function mouseout(ev){
		ismouseDown=false;
		pointnode.style.display='none';
	}	
	app.view.addEventListener('mousedown',mousedown);
	app.view.addEventListener('mousemove',mousemove);
	app.view.addEventListener('mouseup',mouseout);
	app.view.addEventListener('mouseout',mouseout);
	app.view.addEventListener('wheel',wheel);	
	
	//绘制多段线
	let graphics=[],step=0.2;
	function draw(index=0){
		graphics[index] && graphics[index].destroy();//销毁上一次渲染实例
		graphics[index] = new PIXI.Graphics();
		if(!cacheData.y[index] && cacheData.y[index].length<=0){
			return;
		}
		//初始化线条样式
		if(!cacheData.lineStyle[index]){
			cacheData.lineStyle[index]={
				width:1,
				color:lineColor[index%lineColor.length],
				name:`line${index+1}`
			}
		}
		let data=getDrawData({x:cacheData.x,y:cacheData.y[index]},start,end,width);		
		let y=transform(data.y);//将数据转换为屏幕坐标
		cacheData.canvasX=[0];
		cacheData.canvasY[index]=y;
		cacheData.currentX=data.x;
		cacheData.currentY[index]=data.y;	
				
		graphics[index].lineStyle({//设置线条的颜色、宽度等属性		
			width:cacheData.lineStyle[index].width,
			color:cacheData.lineStyle[index].color
		});
		graphics[index].moveTo(0,y[0]);//移动到起始点
		let len2=data.y.length;
		let xAxis={x:[0],value:data.x};
		for (let i=1;i<len2;i++){
			let x=i/len2*width;
			if(i==len2-1)x=width;
			xAxis.x.push(x);
			cacheData.canvasX.push(x);
			graphics[index].lineTo(x,y[i]);			
		}
		if(index==0)createXAxis(xAxis);
		app.stage.addChild(graphics[index]);//将 Graphics添加到舞台中显示
	}
	//设置数据
	//data:{x:[],y:[[],[]]}
	function setData(data){
		end=len=data.x.length;
		let min=[],max=[];		
		data.y.forEach((v,k)=>{			
			if(!customYMinMax){
				min.push(getMin(v));
				max.push(getMax(v));
			}
			cacheData.x=data.x;
			cacheData.y[k]=v;
		});
		if(!customYMinMax){
			//获取所有数据最大最小值		
			dataMin=getMin(min);
			dataMax=getMax(max);		
		}
		createYAxis();		
		refresh();
	}
	//坐标转换
	function transform(data){
		let res=[];
		let len=data.length;
		let c=dataMax-dataMin;		
		for(let k=0;k<len;k++){		
			res[k]=height-(data[k]-dataMin)/c*height;
		}		
		return res;
	}
	//生成Y轴
	function createYAxis(len=5){
		let num=len-1,htmlStr=[];
		let step=(dataMax-dataMin)/num;
		for (let i=dataMin;i<=dataMax;i+=step){
			let z=Number(i.toFixed(2));
			if(Math.abs(i)<0.01 && i!=0)z=i.toExponential(2);			
			htmlStr.push(`<div class="ichart-left-item" data="${z}"></div>`);			
		}
		leftnode.innerHTML=htmlStr.reverse().join('');
	}
	//生成X轴
	function createXAxis(data,len=8){		
		let num=len-1,htmlStr=[];
		let step=parseInt(data.value.length/num);
		for (let i=0;i<=num;i++){			
			try{
				let index=i*step;
				if(index>=data.value.length)index--;				
				htmlStr.push(`<div class="ichart-bottom-item" data="${data.value[index]}" style="left:${data.x[index]}px"></div>`);
				//console.log(data.x[index]);
			}catch(e){
				console.error(i*step,data.length);
			}
		}
		bottomnode.innerHTML=htmlStr.join('');
		
	}
	//设置样式
	function setStyle(data={}){
		let opts=cacheData.opts;
		for(let i in data)opts[i]=data[i];
		if(opts.unitY)leftnode.setAttribute('unit',opts.unitY)
		if(opts.unitX)bottomnode.setAttribute('unit',opts.unitX)
		if(!opts.left)opts.left=60;
		if(!opts.right)opts.right=20;
		if(!opts.bottom)opts.bottom=40;
		if(!opts.top)opts.top=20;
		leftnode.style.width=`${opts.left}px`;
		pnode.style.paddingTop=`${opts.top}px`;	
		pnode.style.width=`${opts.width}px`;
		pnode.style.height=`${opts.height}px`;

		//设置Y轴最大最小值
		setYAxisRange(opts.minY,opts.maxY)
		//canvas宽度计算
		width=opts.width-opts.left-opts.right;
		topnode.style.width=`${width}px`;
		topnode.style.background=opts.background || 'transparent';
		//canvas高度计算
		bottomnode.style.height=`${opts.bottom}px`;
		height=opts.height-opts.bottom-opts.top;
		leftnode.style.height=topnode.style.height=`${height}px`;
		app.renderer.resize(width,height);
		refresh();
	}
	//设置线条样式
	function setLineStyle(opts){
		for(let k=0;k<opts.length;k++){			
			let v=opts[k];
			for(let i in v){
				if(!cacheData.lineStyle[k])cacheData.lineStyle[k]={
					width:1,
					color:lineColor[k%lineColor.length],
					name:`line${k+1}`
				};
				cacheData.lineStyle[k][i]=v[i];
			}
			draw(k);
		}
	}
	//刷新
	function refresh(){
		for(let i=0;i<cacheData.y.length;i++){
			draw(i);
		}
	}
	//鼠标在canvas移动时（非拖动）
	function canvasMove(index){
		//console.log(cacheData.currentX[index],cacheData.currentY[0][index]);
		//pointnode.style.top=`${cacheData.canvasY[0][index]}px`;
		pointnode.style.left=`${cacheData.canvasX[index]}px`;
		pointnode.style.display='block';
		if(!cacheData.opts.showTip){
			tipnode.style.display='none';
			return;
		}
		tipnode.style.display='block';
		if(cacheData.canvasX[index]>width*0.5){			
			tipnode.style.left=`-${tipnode.offsetWidth+10}px`;
		}else{
			tipnode.style.left="10px";
		}
		let res=[];
		tipTitlenode.innerHTML=cacheData.currentX[index];
		cacheData.lineStyle.forEach((v,k)=>{
			res.push(`
			<div class="ichart-right-tip-line">
				<span class="ichart-right-tip-color" style="background:${v.color}"></span>
				${v.name}：${cacheData.currentY[k][index]}
			</div>
			`);			
		});
		tipContentnode.innerHTML=res.join('');	
	}
	//设置Y轴显示范围
	function setYAxisRange(min,max){
		if((min || min==0) && (max || max==0)){
			dataMin=min;
			dataMax=max;
			customYMinMax=true;
		}else{
			customYMinMax=false;
		}
	}
	//销毁
	function destroy(){
		app.view.removeEventListener('mousedown',mousedown);
		app.view.removeEventListener('mousemove',mousemove);
		app.view.removeEventListener('mouseup',mouseout);
		app.view.removeEventListener('mouseout',mouseout);
		app.view.removeEventListener('wheel',wheel);
		cacheData=null;
		dom.innerHTML="";
	}
	setStyle(initopts);
	return {app,setData,setStyle,setLineStyle,refresh,destroy,setYAxisRange};
}

//最小值
function getMin(data){
	let len=data.length,res=Number.MAX_VALUE;
	for(let i=0;i<len;i++){
		if(data[i]<res)res=data[i]
	}
	return res;
}
//最大值
function getMax(data){	
	let len=data.length;
	let res=Number.MIN_VALUE;
	for(let i=0;i<len;i++){
		if(data[i]>res)res=data[i]
	}	
	return res;
}
//获取绘制数据(精简数据)
function getDrawData(data,start,end){
	let dataSegment=data.y.slice(start,end);
	if(dataSegment.length>12000){
		let res={x:[],y:[]};
		let step=parseInt(dataSegment.length/6000);
		for(let i=0;i<dataSegment.length;i+=step){
			let tmpdata=dataSegment.slice(i,i+step);
			let min=Math.min(...tmpdata);
			let max=Math.max(...tmpdata);
			let minIndex=tmpdata.indexOf(min)+i+start;
			let maxIndex=tmpdata.indexOf(max)+i+start;
			if(minIndex<maxIndex){
				res.x.push(data.x[minIndex]);
				res.y.push(min);
				res.x.push(data.x[maxIndex]);
				res.y.push(max);
			}else{
				res.x.push(data.x[maxIndex]);
				res.y.push(max);
				res.x.push(data.x[minIndex]);
				res.y.push(min);
			}			
		}
		return res;
	}else{
		return {
			x:data.x.slice(start,end),
			y:dataSegment
		}
	}
}